import { ArrayHelp } from "./ArrayHelp"


// 从数组中取前n项
function take<T>(arr: T[], n: number): T[] {
    if (n >= arr.length) return arr
    const newArr: T[] = []
    for (let i = 0; i < n; i++) {
        newArr.push(arr[i])
    }
    return newArr
}

const newArr = take<number>([1, 3, 5, 2, 5, 9, 5, 7, 8, 6], 5)


// 丢失了一些信息，传入的数组内容是什么内容，返回应该是相同的内容


// 判断数组中的某一项是否满足条件 
// 不具有通用性，只适用于 number 类型的数组
// type callback = (n: number, i: number) => boolean

// type callback<T> = (n: T, i: number) => boolean

interface callback<T> {
    (n: T, i: number): boolean
}

function filter<T>(arr: T[], callback: callback<T>): T[] {
    const newArr: T[] = []
    for (let i = 0; i < arr.length; i++) {
        if (callback(arr[i], i)) {
            newArr.push(arr[i])
        }
    }
    return newArr
}

const arr = filter<string>(['12', '456', '2', '6'], (n) => {
    return n.length > 1
})
console.log(arr); // ['12','456']


const arrhelp = new ArrayHelp<number>([56, 48, 2, 38, 5, 78, 54, 8, 9, 66])
arrhelp.shuffle()


// 泛型约束

interface hasNameProperty {
    name: string
}

// 将某个对象的name属性的每个单词的首字母大写，然后返回该对象
// function nameToUppercase<T extends hasNameProperty>(obj:T):T{
//     obj.name = obj.name.split(" ").map(s=>  s[0].toLocaleUpperCase() + s.substr(1)).join(" ")
//     return obj
// }
// const o = {
//     name:"kevin yuan",
//     age: 18
// }
// const newO = nameToUppercase(o)
// console.log('newO:',newO.name)

// 多泛型

// 将2个数组进行混合 [1,3,4] + ['a','b','c'] ==>  [ 1, 'a', 3, 'b', 4, 'c' ]
function mixinArray<T, T2>(arr1: T[], arr2: T2[]):(T|T2)[] | never {
    if(arr1.length != arr2.length){
        throw new Error('2个数组长度不一致')
    }
    const newArr:(T|T2)[] = []
    for (let i = 0; i < arr1.length; i++) {
        newArr.push(arr1[i])
        newArr.push(arr2[i])
    }
    return newArr
}
// const res = mixinArray<number,string>([1,3,4],['a','b','c'])
const res = mixinArray([1,3,4],['a','b','c'])
console.log('res',res) //  [ 1, 'a', 3, 'b', 4, 'c' ]

